local sharedLibs = game.ReplicatedStorage.SharedLibs;
local oo = require(sharedLibs.BaseLib)
Require = oo.Require;
local co = require(sharedLibs.CoroLib)
Debugger = require(sharedLibs.Debugger);

Signal = require(script.Parent.Signal);

--- Wrap Getter/Setter into a Property
local GSProperty = oo.class();

function GSProperty:constructor(getter, setter, name)
	self.name = name;
	self._changed = Signal.new("Changed");
	self._getter = getter;
	self._setter = setter;
end

function GSProperty:GetValue()
	return self._getter();
end

function GSProperty:SetValue(value)
	if value == self._value then return end;
	
	self._setter(value);
	self._changed:Emit(value);
end

function GSProperty:On(listener)
	self._changed:On(listener);
end

function GSProperty:Off(listener)
	self._changed:Off(listener);
end

function GSProperty:WaitChanged()
	return self._changed:Wait();
end

function GSProperty:WaitEqual(value)
	local curValue = self._getter();
	if curValue == value then return curValue end;
	
	return self._changed:Wait(function(data) return data == value end);
end

function GSProperty:WaitFor(predicate)
	local curValue = self._getter();
	if predicate(curValue) then return curValue end;

	return self._changed:Wait(predicate);
end

return GSProperty;